peforth supports jupyter notebook magic command %f
since v1.15 (released to Pypi on 2018.3.12) with both line magic and cell magic.
If you are running this jupyter notebook page online through mybinder.org then no installation is needed.
If you would like to work on your computer, so you can save changes you made, then
pip install peforth
to install peforth and that's all, assume you already have jupyter notebook installed.
peforth magics are unknown to jupyter notebook at first untill we import peforth
.
In [1]:
import peforth
In [2]:
%f version .s
In [3]:
%f ." Hello World!" cr
The amazing thing here is that the %f
line magic can be used in python code. . .
In [4]:
# use %f line magic in a python code function definition,
def hi():
%f ." Hello World!" cr
# believe it or not, it works!
hi()
In [5]:
%f __main__ :> hi .source
The %f
line magic is compiled into a python statement, that's why. Some more explanations given at the end of this page.
In [6]:
%%f Nothing allowed before %%f except white spaces; everything in this line after %%f is ignored.
\ Demonstrating the peforth interpret mode [for]..[next] loop
5 [for] t@ . space [next] cr
\ For experienced FORTH users
\ Where t@ is like the FORTH word r@ but it fetches TIB stack instead of the traditional
\ FORTH return stack. Because TIB is the only resource that belongs to this interpreting
\ life cycle alone.
Now use the [for]
loop to print a pyramid:
In [7]:
%%f
: star ." *" ;
: 2stars star star ;
: stars for star next ;
star cr 2stars cr 10 [for] 13 t@ - stars cr [next]
In [8]:
x = 123
%f x . cr
The reason why we choose FORTH is for its super flexibility. Now let's redefine the way peforth handles an unknown token, i.e. the x
of the above example. Instead of alerting "Error! x unknown."
we let it try to find the token in the Jupyter Notebook __main__
module object.
Note: peforth v1.16 and newer version is required to play this trick. Since v1.23 the 'unknown' introduced below has become a built-in so we don't need the re-definition. Instead, use marker command '===' to forget it so the 'x' would be an 'unknown' again.
In [9]:
%%f Now we redefine the 'unknown' command (it does nothing by default)
: unknown // ( token -- thing y|n) Try to find the unknown token in __main__
py> getattr(sys.modules['__main__'],pop(),"Ûnknôwn")
py> str(tos())=="Ûnknôwn" if drop false else true then ;
\ here after, when FORTH come accross an unknown token, instead of printing the
\ error message, it try to find the token in python __main__ module name space.
now test again:
In [10]:
y = 'abc'
%f y . cr
%f x . cr
peforth seems know the 'x' and 'y' now while it doesn't. This trick is vary useful when we are studying and we can investigate things in FORTH way.
peforth.ok()
is the peforth interpreter itself. Run peforth.ok()
to shell a level of the FORTH interpreter and exit
command to come back.
In [11]:
# Run this cell to enter peforth console (REPL loop or command line interface)
# Note the Out[ ] of this cell, the `[*]` indicates that the command line interface
# is running. Play with it or copy-paste this line:
# "star cr 2stars cr 10 [for] 13 t@ - stars cr [next] exit"
# to try again the pyramid example above. 'exit' command to terminate.
peforth.ok()
Out[11]:
In [12]:
peforth.dictate(" .' hello world!' cr ") # Note the Out[ ] of this cell
Out[12]:
Observed from the above outputs, peforth.ok()
and peforth.dictate()
both return the peforth module object. This means that we can cascade these functions. The next example sees the type of the 'star' command that we definded above:
In [13]:
%%f
' star \ get the word object, we defined 'star' above remember?
:> type \ get 'type' attribute of the word object
. cr \ show what we have got ... it is a 'colon' word, isn't it?
It's correctly a 'colon' word. The next example in python code is actually doing the same thing as the above FORTH code:
In [14]:
# Example of cascaded functions, to check a given FORTH word's type
type_of_star = peforth.push('star').dictate("(') :> type").pop() # cascaded functions
print(type_of_star)
Where (')
and :>
are peforth words explained by help
command as shown below. Function cascading is very useful for peforth to debug or to investigate your python target code.
Peforth functions that can be called cascadedly are: peforth.ok()
, peforth.dictate()
, peforth.push()
and peforth.execute()
.
In [15]:
%f help (')
In [16]:
%f help :>
More information about peforth are on the wiki of the project on Github.
May the FORTH be with you!
H.C. Chen @ FigTaiwan
Last Edited: 2018.6.27
Optionally if you want ipython to load %f
magic automatically at startup of every jupyter notebook, so you don't need to import peforth
explicitly everytime, what you need to do is to make . . .
this config file:
C:\Users\<your user name>\.ipython\profile_default\ipython_config.py (for Windows)
or
~/.ipython/profile_default/ipython_config.py (for Linux)
this line:
# A list of dotted module names of IPython extensions to load.
c.InteractiveShellApp.extensions = ['peforth']
to have 'peforth' in the list as shown above.
__main__
is a peforth word that returns the main program module object which in the current case is this jupyter notebook. __main__
is the parent module of the funcion hi()
and __main__ :> hi
is the way peforth gets the hi
function object. Finally .source
displays the source code on top of the FORTH data stack which is now the hi
function object. So this line magic:
%f __main__ :> hi cr
is compiled to:
get_ipython().run_line_magic('f', '." Hello World!" cr')
Where 'f'
is apparently the peforth magic command's name.